﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace TeamFoundation.EventBus
{
    /// <summary>
    /// Represents the management functionality.
    /// </summary>
    [WebService(Namespace = Utilities.ManagerNamespace, Description = "Manages TFS bus subscriptions.")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class Management : System.Web.Services.WebService
    {
        /// <summary>
        /// Gets information about a subscription.
        /// </summary>
        /// <param name="name">The name of the subscription.</param>
        /// <returns>The subscription with the specific name.</returns>
        [WebMethod(Description = "Gets information about a subscription.")]
        public EventSubscription GetSubscription(string name)
        {
            name = name.ToLowerInvariant();

            using (var data = new Model.Database())
            {
                var value = (from b in data.SubscriptionSet
                             where b.Name == name
                             select b).FirstOrDefault();
                if (value == null)
                    return null;

                string clientPath = Utilities.ToClientPath(value.MessageQueue);

                try
                {
                    Utilities.CreateMessageQueue(value.MessageQueue);
                }
                catch { }

                return new EventSubscription()
                {
                    Filter = value.Filter,
                    Name = value.Name,
                    Pipe = clientPath
                };
            }
        }

        /// <summary>
        /// Creates a pipe for a subscriber.
        /// </summary>
        /// <param name="subscription"></param>
        /// <returns></returns>
        [WebMethod(Description = "Creates a pipe for a subscriber.")]
        public EventSubscription Update(EventSubscription subscription)
        {
            string oName = subscription.Name;
            subscription.Name = subscription.Name.ToLowerInvariant();
            subscription.Pipe = Utilities.ToClientPath(subscription.Pipe);

            using (var data = new Model.Database())
            {
                var current = (from b in data.SubscriptionSet
                               where b.Name == subscription.Name
                               select b).FirstOrDefault();

                // Create it if it does not exist.
                if (current == null)
                {
                    current = Model.Subscription.CreateSubscription(0, subscription.Name, subscription.Pipe, subscription.Filter);
                    data.AddToSubscriptionSet(current);
                }
                current.Filter = subscription.Filter;
                current.MessageQueue = subscription.Pipe;

                // Create the queue.
                data.SaveChanges();

                // Attempt to create the message queue.
                try
                {
                    Utilities.CreateMessageQueue(subscription.Pipe);
                }
                catch { }

                return subscription;
            }
        }


        /// <summary>
        /// Removes a specific subscription.
        /// </summary>
        /// <param name="subscription">The subscription to remove.</param>
        /// <returns>The subscription to remove.</returns>
        public bool Remove(EventSubscription subscription)
        {
            subscription.Name = subscription.Name.ToLowerInvariant();
            using (var data = new Model.Database())
            {
                var item = (from d in data.SubscriptionSet
                            where d.Name == subscription.Name
                            select d).FirstOrDefault();
                if (item == null)
                {
                    return false;
                }
                else
                {
                    data.DeleteObject(item);
                    data.SaveChanges();
                    return true;
                }
            }
        }

        /// <summary>
        /// Gets a list of all the subscriptions.
        /// </summary>
        /// <returns>A list of all the subscriptions.</returns>
        [WebMethod(Description = "Gets a list of all the subscriptions.")]
        public EventSubscription[] GetAllSubscriptions()
        {
            List<EventSubscription> all = new List<EventSubscription>();
            using (var data = new Model.Database())
            {
                all.AddRange(
                    from b in data.SubscriptionSet
                    select new EventSubscription()
                    {
                        Filter = b.Filter,
                        Name = b.Name,
                        Pipe = b.MessageQueue
                    });
            }
            return all.ToArray();
        }
    }
}
